// Try to find a conversion from a source expression `e` and // a destination type `t`. Expr& standard_conversion(Expr const& e, Type const& t) { // Just forward to the non-const version of this function. // We strip the const qualifier because we're going to be // building new terms. return standard_conversion(modify(e), modify(t)); }
// Search for dependent conversions. This is done in the case that: // // - e has dependent type, // - t is a dependent type, // - or both. // // A dependent conversion is either a standard, conversion conisisting // of a object-to-value conversion and a qualification adjustment, or // it is a conversion admitted by a constraint. Expr& dependent_conversion(Context& cxt, Expr& e, Type& t) { #if 0 // In certain contexts, no conversions are applied. if (cxt.in_requirements()) return e; if (!cxt.current_template_constraints()) return e; // Determine if we can reach the destination type by a // standard set of conversions on the dependent source // expression. Discard that conversion and replace it with // a dependent conversion. try { // FIXME: If an object-to-value conversion is applied, then // we need to also ensure that the type is copy constructible. // Note that copy constructible would also entail move // constructible. Expr& c = standard_conversion(e, t); (void)c; return *new Dependent_conv(t, e); } catch (Translation_error&) { // Fall through... } // Search for a conversion to t among the listed constraints. Expr& cons = *cxt.current_template_constraints(); if (Expr* c = admit_conversion(cxt, cons, e, t)) { return *c; } #endif error(cxt, "no admissible conversion from '{}' to '{}'", e, t); throw Type_error(); }
// Search for a conversion from the source expression e to a value // expression of type t. Expr& standard_conversion_to_value(Context& cxt, Expr& e, Type& t) { return standard_conversion(cxt, e, t); }