On Mon, Apr 8, 2013 at 10:39 PM, Lawrence Crowl <cr...@google.com> wrote: > On 4/8/13, Kenneth Zadeck <zad...@naturalbridge.com> wrote: >> The other problem, which i invite you to use the full power of >> your c++ sorcery on, is the one where defining an operator so >> that wide-int + unsigned hwi is either rejected or properly >> zero extended. If you can do this, I will go along with >> your suggestion that the internal rep should be sign extended. >> Saying that constants are always sign extended seems ok, but there >> are a huge number of places where we convert unsigned hwis as >> the second operand and i do not want that to be a trap. I went >> thru a round of this, where i did not post the patch because i >> could not make this work. And the number of places where you >> want to use an hwi as the second operand dwarfs the number of >> places where you want to use a small integer constant. > > You can use overloading, as in the following, which actually ignores > handling the sign in the representation. > > class number { > unsigned int rep1; > int representation; > public: > number(int arg) : representation(arg) {} > number(unsigned int arg) : representation(arg) {} > friend number operator+(number, int); > friend number operator+(number, unsigned int); > friend number operator+(int, number); > friend number operator+(unsigned int, number); > }; > > number operator+(number n, int si) { > return n.representation + si; > } > > number operator+(number n, unsigned int ui) { > return n.representation + ui; > } > > number operator+(int si, number n) { > return n.representation + si; > } > > number operator+(unsigned int ui, number n) { > return n.representation + ui; > }
That does not work for types larger than int/unsigned int as HOST_WIDE_INT usually is (it's long / unsigned long). When you pass an int or unsigned int to number operator+(unsigned long ui, number n); number operator+(long ui, number n) you get an ambiguity. You can "fix" that by relying on template argument deduction and specialization instead of on overloading and integer conversion rules. > If the argument type is of a template type parameter, then > you can test the template type via > > if (std::is_signed<T>::value) > .... // sign extend > else > .... // zero extend > > See http://www.cplusplus.com/reference/type_traits/is_signed/. Yes, if we want to use the standard library. For what integer types is std::is_signed required to be implemented in C++98 (long long?)? Consider non-GCC host compilers. Richard. > If you want to handle non-builtin types that are asigne dor unsigned, > then you need to add a specialization for is_signed. > > -- > Lawrence Crowl