digitalmars.D.learn - multiqualifier
- sclytrack (218/218) Jun 16 2018 I'm going to post this in learn in order not to disturb "the
I'm going to post this in learn in order not to disturb "the
guys".
Multiqualifiers
---------------
Warning: Stop reading if you don't have time. Tail-const rant in
disguise.
(1) Going from immutable to mutable, one layer deep.
-----------------------------------
In the D programming language const(int ***) means the same as
const int ***
const int *** source; //head-const body-tail-const or just const
const (int **)* destination; //head-mutable body-tail-const
destination = source; //works with ldc2 (1.2.0)
Assigning the source to the destination is possible and the head
which was
initially const becomes mutable. This is possible because a copy
is made
of that head pointer.
const int *** source; //const
const (int *)** destination; //head-body-mutable tail-const
//error
destination = source; //error
Assigning the source to the destination is not possible because
you would
have to alter the initial head. To clarify with invalid D code
(no-code).
//warning: Fake D code
const (int ***) source;
const (int *)dup(*)dupchange(*) destination;
const (int ****) source;
const (int *)dup(*)dupchange(**) destination;
So we don't do this altering of the values and go only one layer
deep. The D
programming language is even able to figure this one layer deep
out with
regard to structs.
struct HeadMutableTailConst
{
const (int*) * pMutableHeadPointer; //head-mutable
body-tail-const
}
const(HeadMutableTailConst) source;
HeadMutableTailConst destination;
//const-head to mutable-head with destination body-tail-const
destination = source; //works with ldc2 (1.2.0)
The important part is that the head is either mutable or const
and the
rest must always be body-tail-const.
1.a) Naming
-----------
Starting to realize I need a different wording. The first pointer
on the right
is the head and the second pointer is the body.
const(int ***)*** tailConst; //tail-const
const(int ******) headTailConst; //head-const body-tail-const
const(int *****)* bodyTailConst; //head-mutable body-tail-const
Which means that body-tail-const can be either
const(int ******) headTailConst; //head-const body-tail-const
const(int *****)* bodyTailConst; //head-mutable body-tail-const
body-tail-const completally ignores the head.
(2) Going the other way.
------------------------
mutable can be assigned to const, and so does immutable.
int *** source;
const(int **)* destination;
destination = source; //works
The destination needs to be body-tail-const not just tail-const.
int **** source;
const(int*)*** destination;
destination = source; //error
struct Container1
{
int * data;
}
struct Container2
{
const(int) * data;
}
Container1 source;
Container2 destination;
destination = source; //error
Both cases "mutable to const tail" and "const head to mutable
head" with
full BODY-TAIL-CONST (or recently head-mutability)
(3) Multiple tails
------------------
3.a
---
A user defined type can have multiple tails so it should have
multiple
qualifiers, one for each tail. I've numbered them here with $1
and $2 in fake
D code or no-code.
//warning: Fake D code
struct MultiTail
{
qual$1 (int) * a; //Mandatory BODY-TAIL-QUAL$1 or head-body-tail
qual$2 (int) * b; //Mandatory BODY-TAIL-QUAL$2
this()(const, immutable)
{
//qual$1 is const
//qual$2 is immutable
}
}
(const, immutable) MultiTail a; //impossible D code.
I'm going to be verbose so. The first "$1" becomes "const" and
the second
"$2" becomes immutable. Field "a" defined as const(int) * a; and
the second
field "b" is immutable(int) * b;
I will use (const) for the multiqualifier between those ().
(const) vs const
3.b
---
warning: fake D code
struct MultiTail
{
qual$1 (int) * a; //mandatory applied to body-tail or
head-body-tail
qual$1 (int) * b;
qual$1 (int) * c;
qual$2 (int) * z;
}
(const, immutable) MultiTail a; //impossible D code.
A qualifier in a multitail qualifier applying to more tails then
the number of
qualifiers in a multiqualifier.
3.c
---
Can you determine that a type is passable to a routine by just
looking at the
multiqualifier?
(immutable, immutable) MultiTail parameter;
void routine( (const, immutable) MultiTail a)
{
}
3.d classes
Since classes are reference types.
class MultiQualifiedType
{
qual$1(int) field; //mandatory on head-body-tail and not just
body-tail for classes
qual$2(int *) other;
}
(immutable, const) MultiQualifiedType a;
Similarly for structs
//--
struct HeadQualified
{
qual$1(int) field;
}
(const) HeadQualified * a; //a is body-tail-const
//--
struct HeadMutableBodyTailQualified
{
qual$1(int) * field;
}
(const) HeadMutableTailQualified * a; //a is not body-tail-const
error
/--
4. Faking it
------------
Containter!(const int) data;
If you want to apply the qualifier to multiple fields you can
separate it from
the type.
Container!(int, const) data;
This creates a different type.
Container!(int, immutable) data;
The qualifier can not participate in the memory layout of the
container.
Let's say that Q1 is the first qualifier that you pass to the
template.
struct Container(T, Q1)
{
static if (is(Q1 == immutable))
{
int * fieldThatExistsOnlyWhenImmutable; //error
}
}
5. multi-tail inout
-------------------
With multi-tail maybe you don't want to pass (immutable)
Container!(Element)
to (const) Container!(Element) but to (inout) Container!(Element).
//warning: fake D code
inout(Element) findStuff( (inout) Container!(Element) cont)
{
}
I guess you can only have one inout here or two inout but they
are the same
inout.
So basically multiqualifiers for "Head-mutable multi-tail-inout"
Container!(inout(Element)) //can't define field member as inout
Container!(Element, inout) //faking it
(inout) Container!(Element) //multiqualifier
tail(inout) Container!(Element) //previous tail const
Do we want to number the inout? I'm too lazy to think. Post it
anyways.
//warning: all fake D code
(inout$2, inout$1) Element findStuff( (inout$1, inout$2)
Container!(Element) cont)
{
...
}
---
class Base
{
qual$1(int) a; //mandatory head-body-tail for classes.
qual$2(int) b;
this() (inout, inout)
{
}
}
auto b = new (immutable, immutable) Base();
---
Jun 16 2018








sclytrack <fake hotmail.com>