Definition at line 263 of file overload.cpp.
| overloaded_routine_rep | ( | const generic & | name, |
| const environment & | env2 | ||
| ) | [inline] |
Definition at line 275 of file overload.cpp.
:
routine_rep (name),
env (env2),
serial (env->serial),
nullary (exception_routine (name)),
fall_back (exception_routine (name)),
status (0) {}
| overloaded_routine_rep | ( | const generic & | name, |
| const vector< routine > & | funs2, | ||
| const environment & | env2, | ||
| const nat & | serial2, | ||
| const routine & | nullary2, | ||
| const table< routine, nat > & | unary2, | ||
| const table< routine, nat > & | binary2, | ||
| const table< routine, vector< nat > > & | n_ary2, | ||
| const routine & | fall_back2, | ||
| const nat & | status2 | ||
| ) | [inline] |
Definition at line 282 of file overload.cpp.
:
routine_rep (name), funs (funs2), env (env2), serial (serial2),
nullary (nullary2), unary (unary2), binary (binary2),
n_ary (n_ary2), fall_back (fall_back2), status (status2) {}
| generic apply | ( | ) | const [inline] |
Definition at line 364 of file overload.cpp.
{
return nullary->apply ();
}
| generic apply | ( | const generic & | x1 ) | const [inline] |
Definition at line 367 of file overload.cpp.
References mmx::is_nil(), and mmx::type().
{
if (is<iterator<generic> > (x1)) {
vector<generic> v;
iterator<generic> it= as<iterator<generic> > (x1);
while (busy (it)) {
generic next= *it; ++it;
v << next;
if (is<exception> (next)) return next;
}
if (N(v) == 0) return apply ();
else if (N(v) == 1) return apply (v[0]);
else if (N(v) == 2) return apply (v[0], v[1]);
else return apply (v);
}
up_to_date ();
routine fun= unary[type (x1)];
if (is_nil (fun)) fun= resolve (vec<generic> (x1));
return fun->apply (x1);
}
| generic apply | ( | const generic & | x1, |
| const generic & | x2 | ||
| ) | const [inline] |
Definition at line 386 of file overload.cpp.
References mmx::is_nil(), and mmx::type().
{
up_to_date ();
nat id1= type (x1), id2= type (x2);
routine fun= binary[binary_id (id1, id2)];
if (is_nil (fun)) fun= resolve (vec<generic> (x1, x2));
return fun->apply (x1, x2);
}
| generic apply | ( | const vector< generic > & | v ) | const [inline] |
Definition at line 393 of file overload.cpp.
References mmx::is_nil(), and mmx::type().
{
up_to_date ();
routine fun= n_ary[type (v)];
if (is_nil (fun)) fun= resolve (v);
return fun->apply (v);
}
| routine clone | ( | ) | const [inline] |
Definition at line 454 of file overload.cpp.
{
return new overloaded_routine_rep
(name, funs, env, serial,
nullary, copy (unary), copy (binary),
copy (n_ary), fall_back, status);
}
| generic function_body | ( | ) | const [inline] |
Definition at line 446 of file overload.cpp.
{
generic r= comma ();
if (status & 1) r= comma (fall_back->function_body (), r);
if (status & 2) r= comma (nullary->function_body (), r);
for (nat i=0; i<N(funs); i++)
r= comma (funs[i]->function_body (), r);
return xsqtuple (r);
}
| generic function_type | ( | ) | const [inline] |
Definition at line 438 of file overload.cpp.
{
generic r= comma ();
if (status & 1) r= comma (fall_back->function_type(), r);
if (status & 2) r= comma (nullary->function_type(), r);
for (nat i=0; i<N(funs); i++)
r= comma (funs[i]->function_type(), r);
return xsqtuple (r);
}
| void invalidate | ( | ) | const [inline] |
Definition at line 295 of file overload.cpp.
Referenced by overloaded_routine_rep::overload().
{
overloaded_routine_rep* me=
const_cast<overloaded_routine_rep*> (this);
me->unary = table<routine,nat> ();
me->binary= table<routine,nat> ();
me->n_ary = table<routine,vector<nat> > ();
me->serial= env->serial;
}
| bool is_overloaded | ( | ) | const [inline] |
Definition at line 436 of file overload.cpp.
{ return true; }
| vector<routine> meanings | ( | ) | const [inline] |
Definition at line 437 of file overload.cpp.
{ return funs; }
| void overload | ( | const routine & | fun ) | const [inline] |
Definition at line 400 of file overload.cpp.
References overloaded_routine_rep::invalidate(), overloaded_routine_rep::signature(), and mmx::via_tuple_routine().
{
if (fun->is_overloaded ()) {
vector<routine> rs= fun->meanings ();
for (nat i=0; i<N(rs); i++)
overload (rs[i]);
return;
}
overloaded_routine_rep* me=
const_cast<overloaded_routine_rep*> (this);
vector<nat> ids= fun->signature ();
/*
if (!using_simple () && exact_eq (fun->name, GEN_TIMES)) {
mmout << fun << "\t: " << type_name (ids) << "\n";
//mmout << "\t: " << env << "\n";
}
*/
if (N(ids) == 0) { me->fall_back= fun; me->status |= 1; }
else if (N(ids) == 1) { me->nullary= fun; me->status |= 2; }
else {
nat i, n= N(funs);
for (i=0; i<n; i++) {
vector<nat> ids2= funs[i]->signature ();
if (cdr (ids) == cdr (ids2)) {
me->funs[i]= fun;
break;
}
}
if (i==n) me->funs << fun;
if (N(ids) == 2 && is_tuple_type (ids[1]))
if (exact_neq (fun->name, GEN_SQTUPLE) ||
ids[1] == type_id<tuple<generic> > ())
me->nullary= via_tuple_routine (fun, vec<nat> (ids[0]), 2);
}
me->invalidate ();
}
| routine resolve | ( | const vector< generic > & | args ) | const [inline] |
Definition at line 308 of file overload.cpp.
References mmx::build(), mmx::conversion_penalty(), mmx::dynamic_routine(), mmx::equalize_grouped_routine(), mmx::exception_routine(), mmx::is_nil(), mmx::specialize_alias_routine(), and mmx::type().
{
overloaded_routine_rep* me=
const_cast<overloaded_routine_rep*> (this);
routine best;
const vector<nat> ids= cons<nat> (0, type (args));
bool exc_args= false;
bool grouped_args= false;
bool genalias_args= false;
for (nat i=1; i<N(ids); i++) {
exc_args = exc_args || ids[i] == type_id<exception> ();
grouped_args = grouped_args || is_tuple_type (ids[i]);
grouped_args = grouped_args || ids[i] == type_id<iterator<generic> > ();
genalias_args= genalias_args || ids[i] == type_id<alias<generic> > ();
}
if (exc_args) best= exception_routine (name);
else if (grouped_args)
best= equalize_grouped_routine (routine (me, true), ids);
else if (genalias_args)
best= specialize_alias_routine (routine (me, true), ids);
else {
vector<nat> best_ids;
nat best_pen= PENALTY_INVALID;
for (nat i=0; i<N(funs); i++) {
vector<nat> fun_ids= funs[i]->signature ();
nat pen= conversion_penalty (env, ids, fun_ids);
//mmout << "Try " << name << ", " << type_name (fun_ids)
//<< " on " << type_name (ids) << "\n";
if (pen <= best_pen && pen < PENALTY_INVALID) {
if (pen < best_pen ||
conversion_penalty (env, fun_ids, best_ids) <
conversion_penalty (env, best_ids, fun_ids))
{
//mmout << " OK, and better (" << pen << ")\n";
best= build (env, funs[i], ids, fun_ids);
best_ids= fun_ids;
best_pen= pen;
}
//else mmout << " OK, but less good (" << pen << ")\n";
}
}
}
if (is_nil (best)) {
bool dyn_flag= false;
for (nat i=0; i<N(args); i++)
if (is<dynamic> (args[i])) dyn_flag= true;
if (dyn_flag) {
// FIXME: routine no longer freed due to circular dependency
best= dynamic_routine (routine (this, true));
}
else best= fall_back;
}
if (N(ids) == 2) me->unary [ids[1]]= best;
else if (N(ids) == 3) me->binary [binary_id (ids[1], ids[2])]= best;
if (N(ids) <= 7) me->n_ary [cdr (ids)]= best;
return best;
}
| vector<nat> signature | ( | ) | const [inline] |
Definition at line 399 of file overload.cpp.
Referenced by overloaded_routine_rep::overload().
{ return vec<nat> (); }
| void up_to_date | ( | ) | const [inline] |
Definition at line 303 of file overload.cpp.
References mmx::is_nil().
{
if (!is_nil (env->next) && env->next_serial != env->next->serial)
env->ensure_up_to_date ();
if (serial != env->serial) invalidate ();
}
1.7.2