www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Choosing between enum arrays or AliasSeqs

reply =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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
}
Aug 24
parent reply Meta <jared771 gmail.com> writes:
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
Aug 24
parent reply =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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
Aug 24
parent reply Jacob Carlborg <doob me.com> writes:
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
Aug 25
parent =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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.
Aug 25