Thread overview
Choosing between enum arrays or AliasSeqs
Aug 24, 2017
Nordlöw
Aug 24, 2017
Meta
Aug 25, 2017
Nordlöw
Aug 25, 2017
Jacob Carlborg
Aug 25, 2017
Nordlöw
August 24, 2017
Given

   enum e = ['a', 'b', 'c'];

   import std.meta : AliasSeq;
   enum a = AliasSeq!['a', 'b', 'c'];

is it somehow possible to convert (at compile-time) `e` to `a`?

Is it cheaper CT-performance wise to use AliasSeq instead of enum static arrays?

My use case is expressed by the TODOs in the following code snippet


import std.algorithm : among;

/** English indefinite articles. */
enum englishIndefiniteArticles = [`a`, `an`];

/** English definite articles. */
enum englishDefiniteArticles = [`the`];

/** English definite articles. */
enum englishArticles = englishIndefiniteArticles ~ englishDefiniteArticles;

/** Check if $(D c) is a Vowel. */
bool isEnglishIndefiniteArticle(C)(C c)
    if (isSomeChar!C)
{
    return cast(bool)c.among!(`a`, `an`); // TODO reuse englishIndefiniteArticles
}

/** Check if $(D c) is a Vowel. */
bool isEnglishDefiniteArticle(C)(C c)
    if (isSomeChar!C)
{
    return cast(bool)c.among!(`the`); // TODO reuse englishDefiniteArticles
}

/** Check if $(D c) is a Vowel. */
bool isEnglishArticle(C)(C c)
    if (isSomeChar!C)
{
    return cast(bool)c.among!(`a`, `an`, `the`); // TODO reuse englishArticles
}

August 24, 2017
On Thursday, 24 August 2017 at 19:41:46 UTC, Nordlöw wrote:
> Given
>
>    enum e = ['a', 'b', 'c'];
>
>    import std.meta : AliasSeq;
>    enum a = AliasSeq!['a', 'b', 'c'];
>
> is it somehow possible to convert (at compile-time) `e` to `a`?
>
> Is it cheaper CT-performance wise to use AliasSeq instead of enum static arrays?
>
> My use case is expressed by the TODOs in the following code snippet
>
>
> import std.algorithm : among;
>
> /** English indefinite articles. */
> enum englishIndefiniteArticles = [`a`, `an`];
>
> /** English definite articles. */
> enum englishDefiniteArticles = [`the`];
>
> /** English definite articles. */
> enum englishArticles = englishIndefiniteArticles ~ englishDefiniteArticles;
>
> /** Check if $(D c) is a Vowel. */
> bool isEnglishIndefiniteArticle(C)(C c)
>     if (isSomeChar!C)
> {
>     return cast(bool)c.among!(`a`, `an`); // TODO reuse englishIndefiniteArticles
> }
>
> /** Check if $(D c) is a Vowel. */
> bool isEnglishDefiniteArticle(C)(C c)
>     if (isSomeChar!C)
> {
>     return cast(bool)c.among!(`the`); // TODO reuse englishDefiniteArticles
> }
>
> /** Check if $(D c) is a Vowel. */
> bool isEnglishArticle(C)(C c)
>     if (isSomeChar!C)
> {
>     return cast(bool)c.among!(`a`, `an`, `the`); // TODO reuse englishArticles
> }

https://dlang.org/phobos/std_meta.html#aliasSeqOf
August 25, 2017
On Thursday, 24 August 2017 at 22:38:29 UTC, Meta wrote:
> https://dlang.org/phobos/std_meta.html#aliasSeqOf

Thanks!

Your advice led to the following sample solution

import std.meta : aliasSeqOf;
immutable englishIndefiniteArticles = [`a`, `an`];
bool isEnglishIndefiniteArticle(S)(S s)
{
    return cast(bool)s.among!(aliasSeqOf!englishIndefiniteArticles);
}

Is this the preferred way?

Could a template-parameter overload to `among` (perhaps calling it something slighty different) be defined that takes an immutable array as argument to prevent the conversion to the `AliasSeq` prior to the call?

More here:

https://github.com/nordlow/phobos-next/blob/c7d9a0f9c3280fc7852584ee2be387646a5f7857/src/grammar.d#L49

August 25, 2017
On 2017-08-25 08:12, Nordlöw wrote:

> Thanks!
> 
> Your advice led to the following sample solution
> 
> import std.meta : aliasSeqOf;
> immutable englishIndefiniteArticles = [`a`, `an`];
> bool isEnglishIndefiniteArticle(S)(S s)
> {
>      return cast(bool)s.among!(aliasSeqOf!englishIndefiniteArticles);
> }
> 
> Is this the preferred way?

Since you're converting the returned index to a bool, can't you use "canFind" instead?

immutable englishIndefiniteArticles = [`a`, `an`];
bool isEnglishIndefiniteArticle(S)(S s)
{
    return englishIndefiniteArticles.canFind(s);
}

> Could a template-parameter overload to `among` (perhaps calling it something slighty different) be defined that takes an immutable array as argument to prevent the conversion to the `AliasSeq` prior to the call?

I guess. Currently none of the existing overloads take an array, immutable or otherwise. They expect the values to be give as separate arguments.

-- 
/Jacob Carlborg
August 25, 2017
On Friday, 25 August 2017 at 08:27:41 UTC, Jacob Carlborg wrote:
> Since you're converting the returned index to a bool, can't you use "canFind" instead?
>
> immutable englishIndefiniteArticles = [`a`, `an`];
> bool isEnglishIndefiniteArticle(S)(S s)
> {
>     return englishIndefiniteArticles.canFind(s);
> }

`s.canFind` has time-complexity O(s.length)

Opposite to the template-parameter overload of `among` which has O(1), making all the difference performance-wise in my case.