#include <cmath>
+#include <cstdint>
#include <limits>
-#include <msp/core/inttypes.h>
#include "format.h"
#include "lexicalcast.h"
using namespace Msp;
-template<typename T>
-struct IsSigned
-{ enum { result = !(static_cast<T>(-1)>0) }; };
-
/* Helper to avoid warnings about an unsigned type never being < 0 */
-template<typename T, bool f = IsSigned<T>::result>
+template<typename T, bool f = is_signed<T>::value>
struct IsNegative
{ static bool eval(T v) { return v<0; } };
struct IsNegative<T, false>
{ static bool eval(T) { return false; } };
+template<typename T, bool f = is_signed<T>::value>
+struct Negate
+{ static T eval(T v) { return -v; } };
+
+template<typename T>
+struct Negate<T, false>
+{ static T eval(T v) { return (~v)+1; } };
+
/* Helper to avoid errors about ambiguous function calls since there are no
overloads of abs for unsigned types */
-template<typename T, bool f = IsSigned<T>::result>
+template<typename T, bool f = is_signed<T>::value>
struct Absolute
{ static T eval(T v) { return v<0 ? -v : v; } };
const char *digits = (f.get_uppercase() ? udigits : ldigits);
if(v)
{
- typename MatchingInt<T>::UnsignedType w = Absolute<T>::eval(v);
+ typename std::make_unsigned<T>::type w = Absolute<T>::eval(v);
while(w)
{
*--ptr = digits[w%base];
}
template<typename T>
-T str_to_int(const std::string &s, const Fmt &f)
+T str_to_int(const string &s, const Fmt &f)
{
if(s.empty())
throw lexical_error("conversion of '' to integer");
- std::string::const_iterator i = s.begin();
+ auto i = s.begin();
// See if the input starts with a sign
bool neg = false;
if(*i=='-')
{
- if(!IsSigned<T>::result)
+ if(is_unsigned<T>::value)
throw lexical_error(format("conversion of '%s' to unsigned integer", s));
neg = true;
++i;
}
if(neg)
- result = -result;
+ result = Negate<T>::eval(result);
return result;
}
if(s.empty())
throw lexical_error("conversion of '' to floating-point");
- std::string::const_iterator i = s.begin();
+ auto i = s.begin();
// See if the input starts with a sign
bool neg = false;
{ c.result(str_to_str(s, c.get_fmt())); }
void operator<<(LexicalConverter &c, const void *p)
-{ c.result(int_to_str(reinterpret_cast<IntPtr>(p), c.get_fmt())); }
+{ c.result(int_to_str(reinterpret_cast<intptr_t>(p), c.get_fmt())); }
/*** operator>> ***/
v = str_to_int<char>(c.get(), c.get_fmt());
else
{
- const std::string &s = c.get();
+ const string &s = c.get();
if(s.empty())
throw lexical_error("conversion of '' to character");
if(s.size()>1)