View mode: basic / threaded / horizontal-split · Log in · Help
May 30, 2012
std.path.buildPath() and string enumeration
Hi,

I've the following enumeration:

enum path : string {

 log1 = "/var/log1",
 log2 = "/var/log2"

}

Now... when I try to do the following:

string subDirectory = "example";

string newPath = buildPath(path.log1, subDirectory);

I get the following errors:

Error: template std.path.buildPath does not match any function template
declaration
Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
template function from argument types !()(path,string)
Error: template std.path.buildPath does not match any function template
declaration
Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
template function from argument types !()(path,string)

Is this a bug in std.path.buildPath() or is there anything I'm doing wrong?
May 30, 2012
Re: std.path.buildPath() and string enumeration
nrgyzer:

> Is this a bug in std.path.buildPath() or is there anything I'm 
> doing wrong?

The signature of buildPath is:

immutable(C)[] buildPath(C)(const(C[])[] paths...);

But your inputs aren't of the same type. Named enum create their 
own type. You give buildPath a type string and a type path, that 
is not a string.

There are various solutions, this compiles, but it's not very 
safe:

buildPath(cast(string)path.log1, subDirectory);

Another solution is to not use a named enum:

enum : string {
    path_log1 = "/var/log1",
    path_log2 = "/var/log2"
}

buildPath(path_log1, subDirectory)

In bugzilla I have asked for an enum property that returns the 
raw value&type of an enum.

Bye,
bearophile
May 30, 2012
Re: std.path.buildPath() and string enumeration
A better solution is to use:

struct Path {
    enum : string {
        log1 = "/var/log1",
        log2 = "/var/log2"
    }
}


Or even just:

struct Path {
    enum string log1 = "/var/log1",
                log2 = "/var/log2";
}

(In D structs, classes and enums start with an upper case).

Bye,
bearophile
May 30, 2012
Re: std.path.buildPath() and string enumeration
== Auszug aus bearophile (bearophileHUGS@lycos.com)'s Artikel
> nrgyzer:
> > Is this a bug in std.path.buildPath() or is there anything I'm
> > doing wrong?
> The signature of buildPath is:
> immutable(C)[] buildPath(C)(const(C[])[] paths...);
> But your inputs aren't of the same type. Named enum create their
> own type. You give buildPath a type string and a type path, that
> is not a string.
> There are various solutions, this compiles, but it's not very
> safe:
> buildPath(cast(string)path.log1, subDirectory);
> Another solution is to not use a named enum:
> enum : string {
>      path_log1 = "/var/log1",
>      path_log2 = "/var/log2"
> }
> buildPath(path_log1, subDirectory)
> In bugzilla I have asked for an enum property that returns the
> raw value&type of an enum.
> Bye,
> bearophile

Alright, thanks... but I want to do the following:

foreach(c; __traits(allMembers, path))
if (!exists(mixin("path." ~ c))) mkdirRecurse(mixin("path." ~ c));

When I use a named enum, I can't use the source above... so I've to cast in the
buildPath()-method to my path enumeration or is there any other chance to
realize the foreach-loop?
May 30, 2012
Re: std.path.buildPath() and string enumeration
On 05/30/12 20:34, nrgyzer wrote:
> Hi,
> 
> I've the following enumeration:
> 
> enum path : string {
> 
>   log1 = "/var/log1",
>   log2 = "/var/log2"
> 
> }
> 
> Now... when I try to do the following:
> 
> string subDirectory = "example";
> 
> string newPath = buildPath(path.log1, subDirectory);
> 
> I get the following errors:
> 
> Error: template std.path.buildPath does not match any function template
> declaration
> Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
> template function from argument types !()(path,string)
> Error: template std.path.buildPath does not match any function template
> declaration
> Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
> template function from argument types !()(path,string)
> 
> Is this a bug in std.path.buildPath() or is there anything I'm doing wrong?
> 

A bug, as an enum member is supposed to implicitly convert to its base type. [1]

You might be able to work-around it like this

  template _path() {
     enum : string {
       log1 = "/var/log1",
       log2 = "/var/log2"
     }
  }
  alias _path!() path;

artur

[1] Actually, D's "typesafe variadic functions" don't play well with certain
other features too, eg

  void f(A...)(A a) {}
  void f()(string[] a...) {}
  f("a", "b"); // expecting the second overload to be called is reasonable,
               // but this isn't what's going to happen.
Top | Discussion index | About this forum | D home