www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - nothrow function to tell if a string can be converted to a number?

reply Timothee Cour <thelastmammoth gmail.com> writes:
I'd like to have a function:

 nothrow bool isNumberLitteral(string a);
unittest{
  assert(isNumberLitteral("1.2"));
  assert(!isNumberLitteral("a1.2"));
  assert(!isNumberLitteral("a.b"));
}

I want it nothrow for efficiency (I'm using it intensively), and try/catch
as below has significant runtime overhead (esp when the exception is
caught):


bool isNumberLitteral(string a){//slow because throws
try{
import std.conv:to;
auto ret=a.to!double;
}
catch
return false;
return true;
}

even this can throw, eg on "a.b" (and uses gc)
bool isNumberLitteral(T=double)(string a){
  import std.conv;
  //ugly hack to avoid throwing;
  if(!a.length||a==".")
  return false;
  string s="0"~a;
  auto x=parse!T(s);
  return s.length==0;
}
Sep 06 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Sep 07, 2013 at 02:00:52AM -0400, Jonathan M Davis wrote:
 On Friday, September 06, 2013 22:38:20 H. S. Teoh wrote:
 On Sat, Sep 07, 2013 at 12:38:58AM -0400, Jonathan M Davis wrote:
[...]
 http://d.puremagic.com/issues/show_bug.cgi?id=6840
 http://d.puremagic.com/issues/show_bug.cgi?id=6843
[...] I like the idea of maybeTo!(). But I'm not sure if it's possible to guarantee performance -- conversion to user-defined types, for example, may involving a ctor that might throw. If so, it's impossible to implement maybeTo!() without using try/catch, so the performance hit will still be there. But at least, it will buy us performance when basic types are used.
If need be, we could go the route of creating a new function which std.conv.to looks for in addition to the cast operator where that function does a conversion without throwing and returns false when it fails or returns a Nullable or something along those lines so that std.conv.to can take advantage of it. And if the type doesn't implement that function, then either it won't work with the version of to which doesn't throw, or that version of to will use a try-catch (though I'd be inclined to make it require that function in order to avoid invisible performance hits).
I like this idea. I propose opConv() for this purpose: module myprogram; struct MyType { bool opConv(T)(T from) { ... // convert T to MyType and store in *this. } }
 But I really don't like the idea of maybeTo as Bearophile describes it
 (as a wrapper around to which catches the exception). I think that we
 really need a version of to which takes care of this (and it could be
 called maybeTo if we wanted, but it needs to not doing any wrapping).
[...] Then what should be done if opConv isn't defined by the target type? Compile error? On Sat, Sep 07, 2013 at 02:57:03PM +0400, Dmitry Olshansky wrote: [...]
 I've been constantly looking for something like:
 
 bool tryTo(T)(ref T dest, ...<same args as in to>)
 
 That either parses successfully or returns false and leaves dest
 unaffected.
[...] I like the name tryTo. Though it may be a bit confusing with try/catch blocks, so I'm not 100% sure. But anyway, that's just bikeshedding. We could implement it something like this: bool tryTo(T, U)(ref T dest, U from) if (is(typeof(dest.opConv(from)) : bool)) { return dest.opConv(from); } T -- Acid falls with the rain; with love comes the pain.
Sep 07 2013