Re: How to port C++ std::is_reference to D ?

2020-06-06 Thread Q. Schroll via Digitalmars-d-learn

On Wednesday, 13 May 2020 at 13:36:14 UTC, wjoe wrote:

On Monday, 11 May 2020 at 19:08:09 UTC, Q. Schroll wrote:

[...]

1. You can have variables ("data members") of reference type 
in structs. (They work like head-const pointers; if D had 
head-const or at least head-const pointers, those would be 
practically the same, only that references cannot be null.)

[...]



That's also something I don't really know how to correctly port 
to D.
Anyways, that was insightful. Thank you very much for your 
explanations.


Another thing that just occurred to me is generating types. Say I 
have an AliasSeq of types. I want to generate a list of delegates 
taking all of them with all combinations of `ref`ness. Example:

alias list = AliasSeq!(int, char, double);
I want the AliasSeq

alias delegates = AliasSeq!(
R delegate(int, char, double),
R delegate(ref int, char, double),
R delegate(int, ref char, double),
R delegate(int, char, ref double),
R delegate(ref int, ref char, double),
...,
R delegate(ref int, ref char, ref double)
);

That would be way easier if `ref` were part of the type (like 
const/immutable/inout/shared are).


Re: How to port C++ std::is_reference to D ?

2020-05-13 Thread wjoe via Digitalmars-d-learn

On Monday, 11 May 2020 at 19:08:09 UTC, Q. Schroll wrote:

[...]

1. You can have variables ("data members") of reference type in 
structs. (They work like head-const pointers; if D had 
head-const or at least head-const pointers, those would be 
practically the same, only that references cannot be null.)

[...]



That's also something I don't really know how to correctly port 
to D.
Anyways, that was insightful. Thank you very much for your 
explanations.


Re: How to port C++ std::is_reference to D ?

2020-05-11 Thread Q. Schroll via Digitalmars-d-learn

On Saturday, 9 May 2020 at 13:44:27 UTC, Per Nordlöw wrote:

On Wednesday, 6 May 2020 at 17:46:28 UTC, Q. Schroll wrote:

C++'s decision to make references part of the type has some 
advantages, but D didn't do it because of many disadvantages.


Can you outline or give a link describing the advantages of 
C++'s vs D's choice in this matter?


Whether something is an advantage is subjective at least in some 
sense. So whether you in particular consider something I'll list 
here an advantage is basically your choice.


1. You can have variables ("data members") of reference type in 
structs. (They work like head-const pointers; if D had head-const 
or at least head-const pointers, those would be practically the 
same, only that references cannot be null.)
2. Templates can manipulate ref-ness and so on by type building. 
Notably, I had trouble writing templates that handle non-copyable 
types correctly at ctfe. The reason was that implicit moving 
(moving of temporaries) is done entirely by the compiler, but 
manual moving (std.algorithm.mutation.move) does do stuff (it 
doesn't just trick the compiler into moving casting stuff to 
rvalue references).
3. You can have local variables that are references. While not 
really different from pointers, I think they look less scary than 
pointers.
4. Especially in casts, you can trick the compiler into doing 
things without the fear of generating unnecessary code (in C++, 
std::move and std::forward are mere casts that you could do 
yourself but look awkward).


Potentially, I'm missing something.

Personally, I think D did the right thing making references a 
storage class. You can see very early in learning C++ that 
references are only half-way type constructors: They are not 
fully composable. Normally, you can have arrays and pointers to 
any type, but in C++ you can't have pointers to / arrays of 
references.


Re: How to port C++ std::is_reference to D ?

2020-05-09 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 6 May 2020 at 17:46:28 UTC, Q. Schroll wrote:

C++'s decision to make references part of the type has some 
advantages, but D didn't do it because of many disadvantages.


Can you outline or give a link describing the advantages of C++'s 
vs D's choice in this matter?


Re: How to port C++ std::is_reference to D ?

2020-05-07 Thread wjoe via Digitalmars-d-learn

On Wednesday, 6 May 2020 at 16:01:37 UTC, Paul Backus wrote:

On Wednesday, 6 May 2020 at 09:40:47 UTC, wjoe wrote:
yes, I did read the spec. I read the language spec on traits 
as well as std.traits docs as well as searching the internet 
for a solution since day before yesterday. But I couldn't 
bring it together because


  } else static if (__traits(isRef, T)) {

compiles, but e.g.

   assert (modifier!(ref int) == "[out] ");

doesn't.
Anyways, thanks for your reply.


D doesn't have reference *types*, it only has reference 
*parameters*. Here's an example:


void fun(ref int r, int v) {
static assert(is(typeof(r) == int)); // note: not `ref int`
static assert(is(typeof(r) == typeof(v))); // `ref` makes 
no difference to type


static assert(__traits(isRef, r)); // note: not 
`__traits(isRef, typeof(r))`

static assert(!__traits(isRef, v));
}


Hello Paul, thanks for the explanation. This is quite the dilemma 
then. What this guy does in his library is he builds a static 
array at compile time and populates it with const and ref type 
names.


Re: How to port C++ std::is_reference to D ?

2020-05-06 Thread Q. Schroll via Digitalmars-d-learn

On Wednesday, 6 May 2020 at 09:07:22 UTC, wjoe wrote:

Hello,

I'm choking on a piece of C++ I have no idea about how to 
translate to D.


std::is_reference


In general, you can't. In D, `ref` is not part of the type, it's 
a "storage class", and as such it is a property that a function 
parameter can have alongside its type. I.e. in C++, it makes 
sense to ask: "Is that parameter's type a reference type?" But in 
D it doesn't; you could ask: "Is the parameter given by 
reference?" ("Does the parameter have the storage class `ref` [or 
`out` to be complete]?")


C++'s decision to make references part of the type has some 
advantages, but D didn't do it because of many disadvantages.


Re: How to port C++ std::is_reference to D ?

2020-05-06 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 6 May 2020 at 09:40:47 UTC, wjoe wrote:
yes, I did read the spec. I read the language spec on traits as 
well as std.traits docs as well as searching the internet for a 
solution since day before yesterday. But I couldn't bring it 
together because


  } else static if (__traits(isRef, T)) {

compiles, but e.g.

   assert (modifier!(ref int) == "[out] ");

doesn't.
Anyways, thanks for your reply.


D doesn't have reference *types*, it only has reference 
*parameters*. Here's an example:


void fun(ref int r, int v) {
static assert(is(typeof(r) == int)); // note: not `ref int`
static assert(is(typeof(r) == typeof(v))); // `ref` makes no 
difference to type


static assert(__traits(isRef, r)); // note: not 
`__traits(isRef, typeof(r))`

static assert(!__traits(isRef, v));
}


Re: How to port C++ std::is_reference to D ?

2020-05-06 Thread drug via Digitalmars-d-learn

06.05.2020 12:07, wjoe пишет:

Hello,

I'm choking on a piece of C++ I have no idea about how to translate to D.

   template      typename std::enable_if< std::is_const::value == true, 
void>::type* = nullptr>

     constexpr const char *modifier() const {
     return "[in] ";
     }

   template      typename std::enable_if< std::is_reference::value == true, 
void>::type* = nullptr>

     constexpr const char *modifier() const {
     return "[out] ";
     }

my attempt at it is like this:

   template modifier(T) {

   static if (is (T==const)) {

   const char* modifier = "[in] ";

   } else static if (/* T is a reference ?*/) { // [*]

   const char* modifier = "[out] ";
   }
   }

but even if I could e.g. say something like
   is(T == ref R, R),
   auto a = modifier!(ref T);
wouldn't work.





did you try https://dlang.org/spec/traits.html#isRef?


How to port C++ std::is_reference to D ?

2020-05-06 Thread wjoe via Digitalmars-d-learn

Hello,

I'm choking on a piece of C++ I have no idea about how to 
translate to D.


  template typename std::enable_if< std::is_const::value == true, 
void>::type* = nullptr>

constexpr const char *modifier() const {
return "[in] ";
}

  template typename std::enable_if< std::is_reference::value == 
true, void>::type* = nullptr>

constexpr const char *modifier() const {
return "[out] ";
}

my attempt at it is like this:

  template modifier(T) {

  static if (is (T==const)) {

  const char* modifier = "[in] ";

  } else static if (/* T is a reference ?*/) { // [*]

  const char* modifier = "[out] ";
  }
  }

but even if I could e.g. say something like
  is(T == ref R, R),
  auto a = modifier!(ref T);
wouldn't work.





Re: How to port C++ std::is_reference to D ?

2020-05-06 Thread wjoe via Digitalmars-d-learn

On Wednesday, 6 May 2020 at 09:19:10 UTC, drug wrote:

06.05.2020 12:07, wjoe пишет:

Hello,

I'm choking on a piece of C++ I have no idea about how to 
translate to D.


   template      typename std::enable_if< std::is_const::value == 
true, void>::type* = nullptr>

     constexpr const char *modifier() const {
     return "[in] ";
     }

   template      typename std::enable_if< std::is_reference::value 
== true, void>::type* = nullptr>

     constexpr const char *modifier() const {
     return "[out] ";
     }

my attempt at it is like this:

   template modifier(T) {

   static if (is (T==const)) {

   const char* modifier = "[in] ";

   } else static if (/* T is a reference ?*/) { // [*]

   const char* modifier = "[out] ";
   }
   }

but even if I could e.g. say something like
   is(T == ref R, R),
   auto a = modifier!(ref T);
wouldn't work.





did you try https://dlang.org/spec/traits.html#isRef?


yes, I did read the spec. I read the language spec on traits as 
well as std.traits docs as well as searching the internet for a 
solution since day before yesterday. But I couldn't bring it 
together because


  } else static if (__traits(isRef, T)) {

compiles, but e.g.

   assert (modifier!(ref int) == "[out] ");

doesn't.
Anyways, thanks for your reply.