Re: Range checked assignment

2020-09-08 Thread Harry Gillanders via Digitalmars-d-learn

On Tuesday, 8 September 2020 at 14:18:14 UTC, Cecil Ward wrote:

What I would like to do is (in pseudo-code) :

   declare_var my_var : int range 0..7; // i.e. 0 <= val <= 7;

my_var = 6; // ok
my_var = 8; // bang ! static assert fail or assert fail at 
runtime


my_var = 6;
my_var += 2; // bang ! value 8 is > 7

So every assignment is range-checked at either compile-time if 
at all possible or else at runtime. This includes things like 
+= and initialisers of course, not just straight assignment.


I assumed I would have to create a struct type definition and 
handle various operators. How many will I have to handle? I 
would of course make it a template so I can reuse this 
otherwise horribly repetitive code.



If you want to define an integral-like type which is more-or-less 
interchangeable with the native integral types, you'll need to 
provide the following overloads and members:


	* An enum member named `min` which provides an instance of the 
lowest possible value of the type.
	* An enum member named `max` which provides an instance of the 
highest possible value of the type.


* A constructor.

* `opAssign`.
	* `opOpAssign` for the operators: `-`; `+`; `/`; `*`; `%`; `^^`; 
`&`; `|`; `^`; `<<`; `>>`; `>>>`.

* `opEquals`, which should be a const member function.
* `opCmp`, which should be a const member function.
	* `opUnary` for the operators: `-`; `+`; `~`, which should be a 
const member function.
	* `opUnary` for the operators: `--`; `++`, which should be a 
mutable member function.
	* `opBinary` for the operators: `-`; `+`; `/`; `*`; `%`; `^^`; 
`&`; `|`; `^`; `<<`; `>>`; `>>>`, which should be a const member 
function.

* `opCast`, which should be a const member function.

Although in your specific case, implementing the bitwise 
operators may not make sense.
Ideally, all the operator overloads, and the constructor, should 
be able to take any native integral type, and any instances of 
your type, as arguments.


Here's a skeleton implementation of an integral-like type:


import std.algorithm;
import std.traits;

template isConstrainedInt (Instance)
{
enum bool isConstrainedInt = __traits(
isSame,
TemplateOf!Instance,
ConstrainedInt
);
}

template ConstrainedInt (long lower, long upper)
if (lower <= upper)
{
struct ConstrainedInt
{
enum typeof(this) min = typeof(this)(lower);
enum typeof(this) max = typeof(this)(upper);

this (Integer) (const Integer value)
if (isIntegral!Integer || isConstrainedInt!Integer)
{}

void opAssign (Integer) (const Integer value)
if (isIntegral!Integer || isConstrainedInt!Integer)
{}

			void opOpAssign (string operator, Integer) (const Integer 
value)

if (
canFind(
operator,
"-", "+", "/", "*", "%", "^^",
"&", "|", "^",
"<<", ">>", ">>>"
)
&& (isIntegral!Integer || 
isConstrainedInt!Integer)
)
{}

bool opEquals (Integer) (const Integer value) const
if (isIntegral!Integer || isConstrainedInt!Integer)
{}

int opCmp (Integer) (const Integer value) const
if (isIntegral!Integer || isConstrainedInt!Integer)
{}

typeof(this) opUnary (string operator) () const
if (
canFind(
operator,
"-", "+",
"~"
)
)
{}

typeof(this) opUnary (string operator) ()
if (canFind(operator, "--", "++"))
{}

			typeof(this) opBinary (string operator, Integer) (const 
Integer value) const

if (
canFind(
operator,
"-", "+", "/", "*", "%", "^^",
"&", "|", "^",
"<<", ">>", ">>>"
)
&& (isIntegral!Integer || 
isConstrainedInt!Integer)
)
 

Re: How to get the element type of an array?

2020-08-24 Thread Harry Gillanders via Digitalmars-d-learn

On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote:
What's the best way to get the element type of an array at 
compile time?


Something like std.range.ElementType except that works on any 
array type. There is std.traits.ForeachType, but it wasn't 
clear if that was the right thing.


--Jon


One way (maybe not the best way) is to use the type of the 
array's ptr property when dereferenced, e.g.


import std.traits : isArray;

template ArrayElementOf (Array)
if (isArray!Array)
{
alias ArrayElementOf = typeof(*Array.init.ptr);
}



Re: How to use GET_X_LPARAM in D ?

2020-05-21 Thread Harry Gillanders via Digitalmars-d-learn

On Thursday, 21 May 2020 at 18:42:47 UTC, Vinod K Chandran wrote:

Hi all,
I need to use the macro GET_X_LPARAM. But compiler says that 
"undefined identifier GET_X_LPARAM". I cant find any modules 
with GET_X_LPARAM defined. Do i miss something ?


GET_X_LPARAM isn't defined in Phobos's Windows bindings, so 
you'll need to

provide the definition yourself.

GET_X_LPARAM is defined as a macro in the windowsx.h header of 
the Windows SDK, as:

#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))

Which can trivially be translated to D as a function, like so:

int GET_X_LPARAM (T) (T lp)
{
import core.sys.windows.windef : LOWORD;

return cast(int) cast(short) LOWORD(lp);
}

Hope this helps :)




Re: countUntil with negated pre-defined predicate?

2020-05-03 Thread Harry Gillanders via Digitalmars-d-learn

On Sunday, 3 May 2020 at 12:19:30 UTC, Robert M. Münch wrote:


I'm doing some cursor-movement in a text-field. So, need to
find out where the cursor should be positioned.



The Unicode Consortium has some documentation related to 
segmenting text that
you may find useful (notably, section 3): 
https://unicode.org/reports/tr29


	size_t drawableCharacterCount (CodePoints) (auto ref 
CodePoints codePoints)


What does this line do?


I'm unsure as to which part is unclear, but an `auto ref` 
parameter[1] in a

function template is essentially a parameter that receives the
argument by reference if the templated type is a value-type,
whereas if the templated type is a reference-type, it receives 
the argument by value.


An explanation as code:

struct SomeValueType
{}

class SomeReferenceType
{}

void theFunction (Type) (auto ref Type thing)
{}


/+ theFunction!SomeValueType expands to: +/
void theFunction (ref SomeValueType thing)
{}

/+ theFunction!SomeReferenceType expands to: +/
void theFunction (SomeReferenceType thing)
{}

One advantage of auto ref parameters is that they accept literals 
as arguments,

unlike a regular `ref` parameter.

[1]: https://dlang.org/spec/template.html#auto-ref-parameters




Re: countUntil with negated pre-defined predicate?

2020-05-02 Thread Harry Gillanders via Digitalmars-d-learn

On Saturday, 2 May 2020 at 18:23:30 UTC, Robert M. Münch wrote:
Or is there an even better way to search for all "drawable 
unicode characters"?


This depends on what you classify as drawable, and what you 
consider to be a character (the joys of Unicode), and why you 
want to search for them anyway.


One way (I haven't verified this) could be to check if any of the 
code-points within a grapheme are graphical[1], and not 
white-space (and are not any other code-point you consider 
non-drawable).


Which could look like so:

import std.algorithm;
import std.range;
import std.uni;

	size_t drawableCharacterCount (CodePoints) (auto ref CodePoints 
codePoints)
	if (isInputRange!CodePoints && is(ElementType!CodePoints : 
dchar))

{
bool isDrawableCodePoint (dchar c)
{
return c.isGraphical() && !c.isWhite();
}

return codePoints.byGrapheme().count!(
g => g[].any!isDrawableCodePoint
);
}

[1]: 
https://www.unicode.org/versions/Unicode13.0.0/ch02.pdf#G286941


---
The source-code in this reply is available for use under the 
terms of Creative Commons CC0 1.0 Universal.





Re: countUntil with negated pre-defined predicate?

2020-05-02 Thread Harry Gillanders via Digitalmars-d-learn

On Saturday, 2 May 2020 at 18:23:30 UTC, Robert M. Münch wrote:

This works:

countUntil!(std.uni.isWhite)("hello world"))

How can I switch this to (not working);

countUntil!(!std.uni.isWhite)("hello world"))

without having to write my own predicate?

Or is there an even better way to search for all "drawable 
unicode characters"?


std.functional.not can do this: 
https://dlang.org/phobos/std_functional.html#not


Is the behaviour of shift expressions with negative left operands defined / portable?

2020-04-28 Thread Harry Gillanders via Digitalmars-d-learn
The spec doesn't seem to explicitly mention what happens when the 
left operand

of a shift expression is signed and negative. [1]
But I know that D follows C's semantics for this sort of stuff, 
and the C
standard specifies that the result of a negative left operand is 
undefined

for `<<`, and implementation-defined for `>>`. [2][3]

Is D's behaviour the same as C in this regard?

[1]: https://dlang.org/spec/expression.html#shift_expressions
[2]: https://port70.net/~nsz/c/c89/c89-draft.html#3.3.7
[3]: https://port70.net/~nsz/c/c11/n1570.html#6.5.7



Re: Using the functions "map" and "any" on tuples in compile time.

2020-04-12 Thread Harry Gillanders via Digitalmars-d-learn

On Sunday, 12 April 2020 at 11:17:39 UTC, realhet wrote:

Hello, anyone can help me make this better?

The functionality I want to achieve is: While serializing the 
fields of a struct, I want it to check the @STORED UDA on every 
field. If there is no fields are marked with @STORED, that 
means every field must be serialized. Otherwise only the marked 
one.


I had problems using map and any, so I come up with this lame 
foreach version: It works, but I think it does it in runtime.


bool anySTORED = false;
static foreach(fieldName; FieldNameTuple!T)
  mixin("anySTORED |= hasUDA!(data.*, 
STORED);".replace("*", fieldName));


static foreach(fieldName; FieldNameTuple!T){{
  mixin("const thisSTORED = hasUDA!(data.*, 
STORED);".replace("*", fieldName));
  if(thisSTORED || !anySTORED) 
mixin("streamAppend_json!(dense, fieldName)(st, data.*, 
nextIndent);".replace("*", fieldName));

}}

Thanks in advance!

(ps: I just love string mixins, I know :D)


Using a compile-time tuple as a range is easy, turn it into an 
array via an

array literal (surround it in square bracket), e.g.

struct Foo
{
int a;
int b;
}

pragma(msg, [FieldNameTuple!Foo].map!(f => f ~ "_").array());

However, if you were to try that with `any` for `hasUDA`, wherein 
the arguments
for `any`'s predicate are used for `hasUDA`'s template 
parameters, you'll find that it
won't compile. That's because `any`'s predicate is a runtime 
function, executed
at compile-time via CTFE, so the argument technically isn't known 
at compile-time

for the `hasUDA` template, e.g.

struct Foo
{
int a;
int b;
}

enum STORED;

enum bool anyStored = [FieldNameTuple!Foo].any!(
f => hasUDA!(__traits(getMember, Foo, f), STORED)
);

The solution to that is to define a template predicate, and use 
std.meta.anySatisfy,
instead of `any`. Which would accomplish what you want to do, 
with something like so:


string serialiseFields (T) (auto ref T instance)
{
enum bool hasStored (string fieldName) =
hasUDA!(__traits(getMember, T, fieldName), STORED);

enum fields = FieldNameTuple!T;

static if (anySatisfy!(hasStored, fields))
{
enum fieldsToSerialise = Filter!(hasStored, fields);
}
else
{
enum fieldsToSerialise = fields;
}


string serialise (string name, T) (auto ref T value)
{
return format!(name ~ " = %s")(value);
}

string serialised;


static foreach (field; fieldsToSerialise)
{
			serialised ~= serialise!field(__traits(getMember, instance, 
field)) ~ "\n";

}


return serialised;
}

---

This source code in this reply is licensed under the terms of 
Creative Commons CC0 1.0.