Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 29, 2015 Create custom data types | ||||
---|---|---|---|---|
| ||||
Hi, Is it possible to create simple D user-defined data types without the use of classes and other OOP? For example, in Ada is done as follows: ----- type balance is new Integer range -32_000 .. 32_000; |
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On Wednesday, 29 April 2015 at 17:17:07 UTC, Dennis Ritchie wrote:
> Hi,
> Is it possible to create simple D user-defined data types without the use of classes and other OOP?
>
> For example, in Ada is done as follows:
>
> -----
> type balance is new Integer range -32_000 .. 32_000;
I think you can use struct for this together with opAssign etc. functions in it. So, you can define a new variable that uses 3-bytes in memory example. But for 32_000, I think limitations are based on processor, and not the language.
|
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 04/29/2015 10:17 AM, Dennis Ritchie wrote:
> Hi,
> Is it possible to create simple D user-defined data types without the
> use of classes and other OOP?
>
> For example, in Ada is done as follows:
>
> -----
> type balance is new Integer range -32_000 .. 32_000;
Something similar to the following solution should be in Phobos:
import std.exception;
struct Balance
{
int value_;
alias value this;
@property int value() const
{
enforce((value_ >= -32_000) &&
(value_ <= 32_000));
return value_;
}
@property void value(int v)
{
value_ = v;
}
}
unittest
{
auto b = Balance(42);
assert(b == 42);
b = 40_000;
void foo(int) {}
assertThrown(foo(b));
}
void main()
{}
It should be easy to make a template of it. (I really think it should already be in Phobos. :) )
It can be different in several ways: If mutation is never allowed, then the range enforcement can be moved to its constructor. Otherwise, if mutation is allowed and used much less than access, then the enforcement can be moved to the setter.
Ali
|
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wednesday, 29 April 2015 at 17:52:27 UTC, Ali Çehreli wrote: > On 04/29/2015 10:17 AM, Dennis Ritchie wrote: >> Hi, >> Is it possible to create simple D user-defined data types without the >> use of classes and other OOP? >> >> For example, in Ada is done as follows: >> >> ----- >> type balance is new Integer range -32_000 .. 32_000; > > Something similar to the following solution should be in Phobos: > > import std.exception; > > struct Balance > { > int value_; > > alias value this; > > @property int value() const > { > enforce((value_ >= -32_000) && > (value_ <= 32_000)); > > return value_; > } > > @property void value(int v) > { > value_ = v; > } > } > > unittest > { > auto b = Balance(42); > assert(b == 42); > > b = 40_000; > > void foo(int) {} > assertThrown(foo(b)); > } > > void main() > {} Thanks. On Wednesday, 29 April 2015 at 17:52:27 UTC, Ali Çehreli wrote: > It should be easy to make a template of it. (I really think it should already be in Phobos. :) ) Where can I find documentation on this subject? |
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 04/29/2015 12:53 PM, Dennis Ritchie wrote:
> On Wednesday, 29 April 2015 at 17:52:27 UTC, Ali Çehreli wrote:
>> It should be easy to make a template of it. (I really think it should
>> already be in Phobos. :) )
>
> Where can I find documentation on this subject?
Once a piece of code works for a particular type or value, it is easy to convert it to a template by moving the type and the value to the template parameter list and replace all occurrences of those with template parameters:
- int -> T
- -32_000 -> minValue
- 32_000 -> maxValue
Here it is:
import std.exception;
struct CustomInteger(T, T minValue, T maxValue)
{
T value_;
alias value this;
@property T value() const
{
enforce((value_ >= minValue) &&
(value_ <= maxValue));
return value_;
}
@property void value(T v)
{
value_ = v;
}
}
unittest
{
alias Balance = CustomInteger!(int, -32_000, 32_000);
auto b = Balance(42);
assert(b == 42);
b = 40_000;
void foo(int) {}
assertThrown(foo(b));
}
void main()
{}
Ali
|
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wednesday, 29 April 2015 at 21:49:08 UTC, Ali Çehreli wrote:
> On 04/29/2015 12:53 PM, Dennis Ritchie wrote:
>
>> On Wednesday, 29 April 2015 at 17:52:27 UTC, Ali Çehreli wrote:
>>> It should be easy to make a template of it. (I really think it should
>>> already be in Phobos. :) )
>>
>> Where can I find documentation on this subject?
>
> Once a piece of code works for a particular type or value, it is easy to convert it to a template by moving the type and the value to the template parameter list and replace all occurrences of those with template parameters:
>
> - int -> T
>
> - -32_000 -> minValue
>
> - 32_000 -> maxValue
>
> Here it is:
>
> import std.exception;
>
> struct CustomInteger(T, T minValue, T maxValue)
> {
> T value_;
>
> alias value this;
>
> @property T value() const
> {
> enforce((value_ >= minValue) &&
> (value_ <= maxValue));
>
> return value_;
> }
>
> @property void value(T v)
> {
> value_ = v;
> }
> }
>
> unittest
> {
> alias Balance = CustomInteger!(int, -32_000, 32_000);
>
> auto b = Balance(42);
> assert(b == 42);
>
> b = 40_000;
>
> void foo(int) {}
> assertThrown(foo(b));
> }
>
> void main()
> {}
>
> Ali
Thanks. And how can I stop all attempts to perform actions arifmiticheskih the type int? Ie action to "t += b;" suppressed to compile.
-----
import std.exception, std.stdio;
struct CustomInteger(T, T minValue, T maxValue)
{
T value_;
alias value this;
@property T value() const
{
enforce((value_ >= minValue) &&
(value_ <= maxValue));
return value_;
}
@property void value(T v)
{
value_ = v;
}
}
void main()
{
alias Balance = CustomInteger!(int, -32_000, 32_000);
auto b = Balance(42);
// b += 5; // Error: 'b += 5' is not a scalar,
// it is a CustomInteger!(int, -32000, 32000)
int t = 4;
t += b; // OK
writeln(b); // prints 46
}
|
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 04/29/2015 03:48 PM, Dennis Ritchie wrote: > Thanks. And how can I stop all attempts to perform actions > arifmiticheskih the type int? Ie action to "t += b;" suppressed to compile. Some operator overloading is needed. I am pretty sure someone must have implemented such a type. What I add below probably addresses just what you ask. I would like to see others chime in with their solutions or potentially the solutions that are already in Phobos. Continued inline... > > ----- > import std.exception, std.stdio; > > struct CustomInteger(T, T minValue, T maxValue) > { > T value_; > > alias value this; > > @property T value() const > { > enforce((value_ >= minValue) && > (value_ <= maxValue)); > > return value_; > } > > @property void value(T v) > { > value_ = v; > } Add this: ref CustomInteger opOpAssign(string op, T2)(T2 rhs) { static if (is (T2 == CustomInteger)) { mixin("value_ " ~ op ~ "= rhs.value_;"); return this; } else { return this.opOpAssign!(op, CustomInteger)(CustomInteger(rhs)); } } > } > > void main() > { > alias Balance = CustomInteger!(int, -32_000, 32_000); > > auto b = Balance(42); > > // b += 5; // Error: 'b += 5' is not a scalar, > // it is a CustomInteger!(int, -32000, 32000) Now this works: b += 5; assert(b == 47); b += b; assert(b == 94); > > int t = 4; > > t += b; // OK > > writeln(b); // prints 46 > } Ali |
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 04/29/2015 04:16 PM, Ali Çehreli wrote: > ref CustomInteger opOpAssign(string op, T2)(T2 rhs) > { > static if (is (T2 == CustomInteger)) { > mixin("value_ " ~ op ~ "= rhs.value_;"); > return this; > > } else { > return this.opOpAssign!(op, > CustomInteger)(CustomInteger(rhs)); Playing a little more, the following shorter equivalent of the last line works as well: return opOpAssign!op(CustomInteger(rhs)); Ali |
April 29, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wednesday, 29 April 2015 at 23:22:43 UTC, Ali Çehreli wrote:
> On 04/29/2015 04:16 PM, Ali Çehreli wrote:
>
>> ref CustomInteger opOpAssign(string op, T2)(T2 rhs)
>> {
>> static if (is (T2 == CustomInteger)) {
>> mixin("value_ " ~ op ~ "= rhs.value_;");
>> return this;
>>
>> } else {
>> return this.opOpAssign!(op,
>> CustomInteger)(CustomInteger(rhs));
>
> Playing a little more, the following shorter equivalent of the last line works as well:
>
> return opOpAssign!op(CustomInteger(rhs));
>
> Ali
How do I disable it?
I need to prohibit all operations to the type int.
-----
auto b = Balance(42);
int t = 4;
t += b; // error in compile time
|
April 30, 2015 Re: Create custom data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 04/29/2015 04:30 PM, Dennis Ritchie wrote: > On Wednesday, 29 April 2015 at 23:22:43 UTC, Ali Çehreli wrote: >> On 04/29/2015 04:16 PM, Ali Çehreli wrote: >> >>> ref CustomInteger opOpAssign(string op, T2)(T2 rhs) >>> { >>> static if (is (T2 == CustomInteger)) { >>> mixin("value_ " ~ op ~ "= rhs.value_;"); >>> return this; >>> >>> } else { >>> return this.opOpAssign!(op, >>> CustomInteger)(CustomInteger(rhs)); >> >> Playing a little more, the following shorter equivalent of the last >> line works as well: >> >> return opOpAssign!op(CustomInteger(rhs)); >> >> Ali > > How do I disable it? I think I don't understand the requirements here probably because I don't know Ada and I don't have time to even think about such a type. Sorry. :-/ > I need to prohibit all operations to the type int. > > ----- > auto b = Balance(42); > > int t = 4; > > t += b; // error in compile time That works because of 'alias this'. I would remove that line and start adding more and more operator overloads as needed. Ali |
Copyright © 1999-2021 by the D Language Foundation