multiqualifier
sclytrack
fake at hotmail.com
Sat Jun 16 18:39:35 UTC 2018
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();
---
More information about the Digitalmars-d-learn
mailing list