On 02/13/2018 10:37 PM, Martin Sebor wrote:
> On 02/13/2018 01:59 PM, Manuel López-Ibáñez wrote:
>>
> Here's a sketch of what I tried to do:
> 
>   struct IntegerConverter
>   {
>     union {
>       tree t;
>       unsigned HOST_WIDE_INT hwi;
>       // buffer for offset_int, wide_int, etc.
>     } value;
> 
>     IntegerConverter (tree t)
>     {
>       value.t = t;
>     }
> 
>     IntegerConverter (unsigned HOST_WIDE_INT x)
>     {
>       value.x = x;
>     }
> 
>     ...
>   };
> 
>   void error_n (int, const IntegerConverter &, const char*, ...);
>   ...
> 
> With that, the call
> 
>   error_n (loc, t, "%E thing", "%E things", t);
> 
> works when t is a tree, and the call to the same function
> 
>   error_n (loc, i, "%wu thing", "%wu things", i);
> 
> also works when i is a HOST_WIDE_INT.  I chose this approach
> to avoid introducing additional overloads of the error_n()
> functions.

Instead of a class that has to have a constructor for every type
you want to pass as plural selector to the _n functions, which
increases coupling, I'd suggest using a conversion function, and
overload that.  I.e., something like, in the core diagnostics code:

static inline unsigned HOST_WIDE_INT
as_plural_form (unsigned HOST_WIDE_INT val)
{
  return val;
}

/* In some tree-diagnostics header.  */

static inline unsigned HOST_WIDE_INT
as_plural_form (tree t)
{
   // extract & return a HWI
}

/* In some whatever-other-type-diagnostics header.  */

static inline unsigned HOST_WIDE_INT
as_plural_form (whatever_other_type v)
{
   // like above
}

and then you call error_n and other similar functions like this:

    error_n (loc, u, "%u thing", "%u things", u); 
    error_n (loc, as_plural_form (u), "%u thing", "%u things", u); 
    error_n (loc, as_plural_form (t), "%E thing", "%E things", t); 
    error_n (loc, as_plural_form (i), "%wu thing", "%wu things", i);

This is similar in spirit to std::to_string, etc.

BTW, the "plural_form" naming above comes from ngettext's documentation
of the N parameter:

  char * ngettext (const char *msgid1, const char *msgid2, unsigned long int n);

  "The parameter n is used to determine the plural form."

Pedro Alves

Reply via email to