www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 21169] New: make checkedint as a drop-in replacement of


          Issue ID: 21169
           Summary: make checkedint as a drop-in replacement of native
           Product: D
           Version: D2
          Hardware: All
               URL: http://dlang.org/
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P3
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: mingwu gmail.com

This is follow up of this discussion:

https://forum.dlang.org/thread/omskttpjhwmmhifymiha forum.dlang.org

We need to improve the following 8 points to make checkedint as a drop-in
replacement of native int/long, i.e minimal or 0 modification of user's
existing code that use native integers.

(This is a follow-up from the other thread: 
https://forum.dlang.org/thread/rdrqedmbknwrppbfixll forum.dlang.org)

I start this new thread to discuss and improve the usage of
 as a drop-in replacement of native long.


`Checked` is a struct, try to use it as a `long` require some substantial
change of existing code that previously use native long.

I list 8 things I've found below. Suggestions or PR welcome, e.g. even on how
to improve the current implementation of `struct Checked`, or help from the


alias Long = Checked!long;

void use_checked() {
  long la, lb, lc;  // native
  Long ca, cb, cc;  // checkedint

  // 0. as array literal
  long[] larr = [1, 2, 3];
//Long[] carr = [1, 2, 3];  // Error: cannot implicitly convert expression [1,
2, 3] of type int[] to Checked!(long, Abort)[]
  Long[] carr = [checked(1L), checked(2L), checked(3L)];  // more verbose

  // 1. checkedint cannot be chain assigned
  la = lb = lc = 0;
//ca = cb = cc = 0;  // Error: expression cc.opAssign(0) is void and has no
  ca = 0;  // have to do separately
  cb = 0;
  cc = 0;

  // 2. have to use .get to call math func
//writeln(std.math.sgn(ca));  // Error: template std.math.sgn cannot deduce
function from argument types !()(Checked!(long, Abort)), candidates are:
//writeln(std.math.abs(ca));  // Error: template instance
std.math.abs!(Checked!(long, Abort)) error instantiating
  writeln(std.math.sgn(ca.get));  // need .get
  writeln(std.math.abs(ca.get));  // need .get

  // 3. no opBinaryLeft
  lc = la * lb;
//cc = la * cb;  // Error: can only * a pointer, not a int
  cc = cb * la;  // have to switch order

  // 4. std.conv don't work
  double d = 0;
  lb = d.to!long;
//cb = d.to!Long;  // Error: template instance std.conv.to!(Checked!(long,
Abort)).to!double error instantiating
  cb = lround(d);

  lb = "0".to!long;
//cb = "0".to!Long; // Error: template std.conv.toImpl cannot deduce function
from argument types !(Checked!(long, Abort))(string), candidates are:
  cb = "0".to!long; // work around ok

  // 5. cannot assign to shared
  static struct S {
    shared long sl;
    shared Long sL;
  S s;
  s.sl = la;
//s.sL = la;  // Error: template std.experimental.checkedint.Checked!(long,
Abort).Checked.opAssign cannot deduce function from argument types !()(long)
shared, candidates are:
  cast()s.sL = la;  // need the `cast`

  // 6. format %d won't work
  writefln("%04d", la);      // output: 0000
//writefln("%04d", ca);      // Expected '%s' format specifier for type
'Checked!(long, Abort)'
  writefln("%s",   ca);      // output: Checked!(long, Abort)(0), can this be
just be 0?
  writefln("%04d", ca.get);  // output: 0000

  // 7. atomic won't work
  core.atomic.atomicOp!"+="(s.sl, lb);
//core.atomic.atomicOp!"+="(s.sL, cb);  // Error: template instance
core.atomic.atomicOp!("+=", Checked!(long, Abort), Checked!(long, Abort)) error
//core.atomic.atomicFetchAdd(s.sL, cb);  // Error: template
core.atomic.atomicFetchAdd cannot deduce function from argument types
!()(shared(Checked!(long, Abort)), Checked!(long, Abort)), candidates are:

Aug 16 2020