On 4/30/21 9:24 AM, sighoya wrote:
On Friday, 30 April 2021 at 01:30:54 UTC, Steven Schveighoffer wrote:
In my case, for value of a certain type in the loop, I was storing a
specific field from the first one I found, and then verifying that all
the other values of that type (not exactly the same type, but similar)
had the same value for that field, otherwise it was an error.
I could have done it in 2 loops, but it's wasteful.
I have problems to grok exactly what you're talking about, can you
provide some neat and small example for this?
I'll just show you the code here. This is from my (up and coming) sql
builder project.
A `ColumnDef!T` is an sql table column of type `T`, which contains an
expression describing the column, and a table definition of where the
column comes from. `TableDef` is const inside the column def:
```d
struct ColumnDef(T)
{
const TableDef table;
ExprString expr;
alias type = T;
}
```
Now, what if you wanted a "computed" column? that is, you wanted to
define a column with a type, but that is computed from other columns?
Like `select total - tax as netcost from sometable`
What I want to create is something that returns a ColumnDef from an
arbitrary expression. But there is only one table definition, so if you
want to return a ColumnDef, you need to ensure there is only one source
table. So here is my code that does that:
```d
ColumnDef!T exprCol(T, Args...)(Args args)
{
// first, find all columns, and ensure that table defs are all from the
// same table (a ColumnDef cannot have multiple tables).
const(TableDef)* tabledef;
foreach(ref arg; args)
{
static if(is(typeof(arg) == ColumnDef!U, U))
{
if(tabledef && arg.table != *tabledef)
throw new Exception("can't have multiple tabledefs in
the expression");
else
tabledef = &arg.table;
}
}
assert(tabledef !is null);
// build the expr string
ExprString expr;
foreach(ref a; args)
{
static if(is(typeof(a) == string))
expr ~= a;
else
expr ~= a.expr;
}
return ColumnDef!(T)(*tabledef, expr);
}
```
The pointer abstraction works perfectly, but if there was no way to use
that abstraction, there aren't any D facilities to allow this. It's
really tail-const that I need.
I could have looped 2x over the args, and used an inner function to
fetch the first one (or maybe used a staticIndexOf to get the first
ColumnDef thing), and a second loop to verify all the remaining args
have the same table def, but this loop works just as designed and is
super-readable.
-Steve