what is the proper syntax to inherit a pair of nested classes using templates ?

2021-06-10 Thread someone via Digitalmars-d-learn
I am needing pairs of specific nested classes with already-coded 
collection management; eg: classComputers having nested 
classComputer as following (as seen by client code that is):


- classComputer ← objComputers.add("ID1", "workstation # 1")
- classComputer ← objComputers.add("ID2", "workstation # 2")
- classComputer ← objComputers.add("ID3", "workstation # 3")
- classComputer ← objComputers.first
- classComputer ← objComputers.last
- classComputer ← objComputers[2].previous
- classComputer ← objComputers[2].next
- string ← objComputers[2].name
- string ← objComputers["ID2"].name
- classComputer ← objComputers["ID2"].next
- classComputer ← objComputers["ID2"].previous
- size_t ← objComputers.count
- bool ← objComputers.empty
- bool ← objComputers.remove("ID3")
- bool ← objComputers.removeAll()
- classComputers ← objComputers.filterByWhatever("...") ... 
extended functionality like this specifically implemented 
on-demand by client code


... so classComputers should inherit the collection management 
infrastructure (ie: the store itself and associated 
properties/methods to handle it) while classComputer should 
inherit collection access with this.outer (or the like) ... now 
let's see my implementation:


```d
abstract public class classCollectionItems(
   typeItems,
   typeItem
   ) {

   /// (1) given type for collection items; eg: classComputers
   /// (2) given type for collection item;  eg: classComputer

   typeItems lhs;
   typeItems rhs;

   int opApply(int delegate(typeItem) dg) { /// boilerplate code 
to handle the class's default collection


  int lintResult = 0; /// must find a better name

		foreach (lobjItem; items) { /// looping over the computers 
starting in current node


			lintResult = dg(lobjItem); /// passing single object to the 
loop body


if (lintResult != 0) { break; }

}

  if (lintResult != 0 && lhs ! is null) { lintResult = 
lhs.opApply(dg); } /// recursing child nodes
  if (lintResult != 0 && rhs ! is null) { lintResult = 
rhs.opApply(dg); } /// recursing child nodes


  return lintResult;

   }

   final public typeItem add(in string lstrID) { return false; };
   final public bool remove(in string lstrID) { return false; };
   final public bool removeAll() { this.items.length = 
cast(size_t) 0; return this.items.length == cast(size_t) 0; };


   final public @property const bool empty() { return 
this.items.empty; }
   final public @property const size_t count() { return 
this.count1; }
   final public @property const size_t count0() { return 
this.items.empty ? cast(size_t) 0 : this.items.length - 
cast(size_t) 1; }
   final public @property const size_t count1() { return 
this.items.empty ? cast(size_t) 0 : this.items.length; }


   final public @property typeItem first() { return null; }
   final public @property typeItem last() { return null; }

   abstract public class classCollectionItem {

  private size_t pintPosition0 = cast(size_t) 0; /// keep in 
mind that array positions are zero-based


  final public @property const size_t position0() { return 
this.pintPosition0; }
  final public @property const size_t position1() { return 
this.pintPosition0 + cast(size_t) 1; }


  final public @property const size_t countAbove() { return 
this.outer.items.empty ? cast(size_t) 0 : this.pintPosition0; }
  final public @property const size_t countBelow() { return 
this.outer.items.empty ? cast(size_t) 0 : this.outer.length - 
this.pintPosition0 - cast(size_t) 1; }


  /// eg: for position0=0 → countAbove=0=(position0=0) & 
countBelow=2=(length=3)-(position0=0)-1
  /// eg: for position0=1 → countAbove=1=(position0=1) & 
countBelow=1=(length=3)-(position0=1)-1
  /// eg: for position0=2 → countAbove=2=(position0=2) & 
countBelow=0=(length=3)-(position0=2)-1


  final public @property typeItem first() { return 
this.outer.items.empty ? null : this.outer.items[cast(size_t) 0]; 
}
  final public @property typeItem previous() { return 
this.outer.items.empty || this.countAbove == cast(size_t) 0 ? 
null : this.outer.items[this.pintPosition0 - cast(size_t) 1]; }
  final public @property typeItem next() { return 
this.outer.items.empty || this.countBelow == cast(size_t) 0 ? 
null : this.outer.items[this.position0 + cast(size_t) 1]; }
  final public @property typeItem last() { return 
this.outer.items.empty ? null : 
this.outer.items[this.outer.items.length - cast(size_t) 1]; }


   }

}
```

... so far so good, now, when I code my specific classes I am 
**not sure which is the correct syntax to inherit the base pair**:


```d
public class classComputers : 
classCollectionItems!(classComputers, 
classComputers.classComputer) { /// seems logical to me


   public class classComputer {}
   public class classComputer : classCollectionItem {}
   public class classComputer : 
classCollectionItems!(classComputers, 
classComputers.classComputer).classCollectionItem {}


}
```


Re: Classes and templates

2016-11-01 Thread Hefferman via Digitalmars-d

On Monday, 31 October 2016 at 22:33:11 UTC, John Colvin wrote:

On Monday, 31 October 2016 at 19:24:46 UTC, Hefferman wrote:

Hello,

I've been trying to implement a class for sorting which 
accepts arrays which "different" data types. Hard to describe, 
here's my example (filename sorting.d):


[...]


Glad to see you're getting helpful responses here, but just an 
FYI: https://forum.dlang.org/group/learn would be a more 
appropriate forum for questions like this.


Thanks to all for replying!

@J.C.: I'll keep it in mind for the next time.


Re: Classes and templates

2016-10-31 Thread John Colvin via Digitalmars-d

On Monday, 31 October 2016 at 19:24:46 UTC, Hefferman wrote:

Hello,

I've been trying to implement a class for sorting which accepts 
arrays which "different" data types. Hard to describe, here's 
my example (filename sorting.d):


[...]


Glad to see you're getting helpful responses here, but just an 
FYI: https://forum.dlang.org/group/learn would be a more 
appropriate forum for questions like this.


Re: Classes and templates

2016-10-31 Thread Kapps via Digitalmars-d

On Monday, 31 October 2016 at 20:25:18 UTC, Hefferman wrote:

for (uint k = 1; k < n; k++) {
if (a[k-1] > a[k]) {
T tmp = a[k];
a[k] = a[k+1];
a[k+1] = tmp;
sorted = false;
}
}
n--;
} while (!sorted);
}
}
[/code]

It gives a Range Violation upon executing, but I guess it's 
part of the algorithm


The value of n is array length, so k reaches (n - 1), therefore 
k+1 gives you n which is out of bounds.


Re: Classes and templates

2016-10-31 Thread Hefferman via Digitalmars-d

On Monday, 31 October 2016 at 20:20:09 UTC, Meta wrote:

[...]

You can't use an un-instantiated template as a type anyway, 
unlike Java. There the above is illegal because of `BubbleSort 
b = ...`. The symbol BubbleSort by itself is not a type; you 
have to instantiate it with template arguments to create a 
type. So you *could* do it like this:


BubbleSort!(typeof(arr)) b = new BubbleSort!(typeof(arr));

But that's too verbose. There's need need to repeat ourselves. 
You can instead use `auto` and omit the type of `b`, which will 
be inferred from the right hand side:


auto b = new BubbleSort!(typeof(arr));


Thanks! This compiled just fine...

[code]
import std.random;
import std.stdio;

void main()
{
immutable uint N = 10_000;

double[] arr = new double[](N);
for (uint k = 0; k < N; k++) arr[k] = uniform(0, N);

auto b = new BubbleSort!(typeof(arr));
b.Sort(arr);
}

public class BubbleSort(T)
{
private T[] a;
private uint n;

public void Sort(T)(T[] a) {
n = a.length;
bubblesort();
}

private void bubblesort() {
bool sorted;

do {
sorted = true;
for (uint k = 1; k < n; k++) {
if (a[k-1] > a[k]) {
T tmp = a[k];
a[k] = a[k+1];
a[k+1] = tmp;
sorted = false;
}
}
n--;
} while (!sorted);
}
}
[/code]

It gives a Range Violation upon executing, but I guess it's part 
of the algorithm


Re: Classes and templates

2016-10-31 Thread Meta via Digitalmars-d

On Monday, 31 October 2016 at 20:06:22 UTC, Hefferman wrote:

On Monday, 31 October 2016 at 19:43:57 UTC, Adam D. Ruppe wrote:

On Monday, 31 October 2016 at 19:24:46 UTC, Hefferman wrote:

Give a template type when crating it

new BubbleSort!(string)

for example


Is it possible to create this using "typeof"?
E. g. "BubbleSort b = new BubbleSort!(typeof(arr));"
Compilation fails with that line


You can't use an un-instantiated template as a type anyway, 
unlike Java. There the above is illegal because of `BubbleSort b 
= ...`. The symbol BubbleSort by itself is not a type; you have 
to instantiate it with template arguments to create a type. So 
you *could* do it like this:


BubbleSort!(typeof(arr)) b = new BubbleSort!(typeof(arr));

But that's too verbose. There's need need to repeat ourselves. 
You can instead use `auto` and omit the type of `b`, which will 
be inferred from the right hand side:


auto b = new BubbleSort!(typeof(arr));


Re: Classes and templates

2016-10-31 Thread Hefferman via Digitalmars-d

On Monday, 31 October 2016 at 19:43:57 UTC, Adam D. Ruppe wrote:

On Monday, 31 October 2016 at 19:24:46 UTC, Hefferman wrote:

Give a template type when crating it

new BubbleSort!(string)

for example


Is it possible to create this using "typeof"?
E. g. "BubbleSort b = new BubbleSort!(typeof(arr));"
Compilation fails with that line


Re: Classes and templates

2016-10-31 Thread Adam D. Ruppe via Digitalmars-d

On Monday, 31 October 2016 at 19:24:46 UTC, Hefferman wrote:
Whenever I try to compile this, it throws an error "class 
sorting.BubbleSort(T) is used as a type". How do I get a 
workaround?


Give a template type when crating it

new BubbleSort!(string)

for example


Classes and templates

2016-10-31 Thread Hefferman via Digitalmars-d

Hello,

I've been trying to implement a class for sorting which accepts 
arrays which "different" data types. Hard to describe, here's my 
example (filename sorting.d):


[code]
import std.random;

void main()
{
immutable uint N = 10_000;

double[] arr = new double[](N);
for (uint k = 0; k < N; k++) arr[k] = uniform(0, N);

BubbleSort b = new BubbleSort();
b.Sort(arr);
}

public class BubbleSort(T)
{
private T[] a;
private uint n;

public void Sort(T)(T[] a) {
this.a = a;
n = a.length;
bubblesort();
}

private void bubblesort() {
bool sorted;

do {
sorted = true;
for (uint k = 0; k < n; k++) {
if (a[k] > a[k+1]) {
T tmp = a[k];
a[k] = a[k+1];
a[k+1] = tmp;
sorted = false;
}
}
n--;
} while (!sorted);
}
}
[/code]

Whenever I try to compile this, it throws an error "class 
sorting.BubbleSort(T) is used as a type". How do I get a 
workaround?